package cn.harry.cabinet.arcface.engine

import android.content.Context
import android.util.Log
import cn.harry.cabinet.arcface.util.ConfigUtil
import com.arcsoft.face.ErrorInfo
import com.arcsoft.face.FaceEngine
import com.arcsoft.face.enums.DetectFaceOrientPriority
import com.arcsoft.face.enums.DetectMode

/**
 * 全局人脸识别引擎管理器
 * 用于复用引擎实例，避免重复初始化，减少内存占用
 */
class FaceEngineManager private constructor() {
    companion object {
        private const val TAG = "FaceEngineManager"

        @Volatile
        private var INSTANCE: FaceEngineManager? = null

        fun getInstance(): FaceEngineManager {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: FaceEngineManager().also { INSTANCE = it }
            }
        }
    }

    // 引擎实例
    private var ftEngine: FaceEngine? = null
    private var frEngine: FaceEngine? = null
    private var flEngine: FaceEngine? = null

    // 引擎状态
    private var isInitialized = false
    private var isDestroyed = false

    // 引用计数，用于管理引擎生命周期
    private var referenceCount = 0

    // 最小引用计数，防止引擎被过早销毁
    private var minReferenceCount = 1

    // 引擎锁，确保线程安全
    private val engineLock = Any()

    /**
     * 预初始化引擎（不增加引用计数）
     * 用于应用启动时的预初始化，确保引擎可用
     */
    fun preInitEngines(context: Context, maxDetectNum: Int = 10): Boolean {
        synchronized(engineLock) {
            if (isDestroyed) {
                Log.w(TAG, "引擎管理器已销毁，无法预初始化")
                return false
            }

            if (isInitialized) {
                Log.d(TAG, "引擎已初始化，无需预初始化")
                return true
            }

            Log.i(TAG, "=== 开始预初始化人脸识别引擎 ===")
            val success = initEngines(context, maxDetectNum)
            if (success) {
                // 设置最小引用计数，防止引擎被过早销毁
                referenceCount = minReferenceCount
                Log.i(TAG, "人脸识别引擎预初始化成功，设置最小引用计数: $minReferenceCount")
            } else {
                Log.e(TAG, "人脸识别引擎预初始化失败")
            }
            return success
        }
    }

    /**
     * 获取引擎实例，如果未初始化则自动初始化
     */
    fun getEngines(
        context: Context,
        maxDetectNum: Int = 10
    ): Triple<FaceEngine?, FaceEngine?, FaceEngine?> {
        synchronized(engineLock) {
            if (isDestroyed) {
                Log.w(TAG, "引擎管理器已销毁，尝试重新初始化")
                val success = reinitializeEngines(context, maxDetectNum)
                if (!success) {
                    Log.e(TAG, "引擎重新初始化失败")
                    return Triple(null, null, null)
                }
            }

            if (!isInitialized) {
                val success = initEngines(context, maxDetectNum)
                if (!success) {
                    Log.e(TAG, "引擎初始化失败")
                    return Triple(null, null, null)
                }
            }

            // 如果这是第一次获取引擎，设置最小引用计数
            if (referenceCount == 0) {
                referenceCount = minReferenceCount
            }
            referenceCount++

            Log.d(TAG, "获取引擎实例，当前引用计数: $referenceCount")

            return Triple(ftEngine, frEngine, flEngine)
        }
    }

    /**
     * 初始化引擎
     */
    private fun initEngines(context: Context, maxDetectNum: Int): Boolean {
        synchronized(engineLock) {
            if (isInitialized) {
                Log.d(TAG, "引擎已初始化，跳过")
                return true
            }

            try {
                Log.i(TAG, "=== 开始初始化人脸识别引擎 ===")

                // 初始化人脸检测引擎 (ftEngine)
                ftEngine = FaceEngine()
                val ftInitCode = ftEngine?.init(
                    context,
                    DetectMode.ASF_DETECT_MODE_VIDEO,
                    ConfigUtil.getFtOrient(context),
                    16,
                    maxDetectNum,
                    FaceEngine.ASF_FACE_DETECT
                ) ?: -1

                if (ftInitCode != ErrorInfo.MOK) {
                    Log.e(TAG, "人脸检测引擎初始化失败: $ftInitCode")
                    return false
                }

                // 初始化人脸识别引擎 (frEngine)
                frEngine = FaceEngine()
                val frInitCode = frEngine?.init(
                    context,
                    DetectMode.ASF_DETECT_MODE_IMAGE,
                    DetectFaceOrientPriority.ASF_OP_0_ONLY,
                    16,
                    maxDetectNum,
                    FaceEngine.ASF_FACE_RECOGNITION
                ) ?: -1

                if (frInitCode != ErrorInfo.MOK) {
                    Log.e(TAG, "人脸识别引擎初始化失败: $frInitCode")
                    return false
                }

                // 初始化活体检测引擎 (flEngine)
                flEngine = FaceEngine()
                val flInitCode = flEngine?.init(
                    context,
                    DetectMode.ASF_DETECT_MODE_IMAGE,
                    DetectFaceOrientPriority.ASF_OP_0_ONLY,
                    16,
                    maxDetectNum,
                    FaceEngine.ASF_LIVENESS
                ) ?: -1

                if (flInitCode != ErrorInfo.MOK) {
                    Log.e(TAG, "活体检测引擎初始化失败: $flInitCode")
                    return false
                }

                isInitialized = true
                Log.i(TAG, "=== 人脸识别引擎初始化成功 ===")
                return true

            } catch (e: Exception) {
                Log.e(TAG, "初始化引擎时发生异常", e)
                cleanupEngines()
                return false
            }
        }
    }

    /**
     * 释放引擎引用
     */
    fun releaseEngines() {
        synchronized(engineLock) {
            if (isDestroyed) {
                Log.w(TAG, "引擎管理器已销毁，无需释放")
                return
            }

            referenceCount--
            Log.d(TAG, "释放引擎引用，当前引用计数: $referenceCount")

            // 当引用计数小于等于最小值时，销毁引擎
            if (referenceCount <= minReferenceCount) {
                Log.i(TAG, "引用计数达到最小值，开始销毁引擎")
                destroyEngines()
            }
        }
    }

    /**
     * 强制销毁引擎（用于应用退出等场景）
     */
    fun forceDestroy() {
        synchronized(engineLock) {
            Log.i(TAG, "强制销毁引擎")
            destroyEngines()
        }
    }

    /**
     * 销毁引擎
     */
    private fun destroyEngines() {
        synchronized(engineLock) {
            if (isDestroyed) {
                return
            }

            try {
                Log.i(TAG, "=== 开始销毁人脸识别引擎 ===")

                // 销毁人脸检测引擎
                if (ftEngine != null) {
                    val code = ftEngine?.unInit() ?: -1
                    Log.d(TAG, "人脸检测引擎销毁结果: $code")
                    ftEngine = null
                }

                // 销毁人脸识别引擎
                if (frEngine != null) {
                    val code = frEngine?.unInit() ?: -1
                    Log.d(TAG, "人脸识别引擎销毁结果: $code")
                    frEngine = null
                }

                // 销毁活体检测引擎
                if (flEngine != null) {
                    val code = flEngine?.unInit() ?: -1
                    Log.d(TAG, "活体检测引擎销毁结果: $code")
                    flEngine = null
                }

                isInitialized = false
                isDestroyed = true
                referenceCount = 0
                minReferenceCount = 1

                Log.i(TAG, "=== 人脸识别引擎销毁完成 ===")

            } catch (e: Exception) {
                Log.e(TAG, "销毁引擎时发生异常", e)
            }
        }
    }

    /**
     * 清理引擎资源（用于异常情况）
     */
    private fun cleanupEngines() {
        try {
            ftEngine?.unInit()
            frEngine?.unInit()
            flEngine?.unInit()

            ftEngine = null
            frEngine = null
            flEngine = null

            isInitialized = false
            referenceCount = 0

            Log.w(TAG, "引擎资源已清理")
        } catch (e: Exception) {
            Log.e(TAG, "清理引擎资源时出错", e)
        }
    }

    /**
     * 检查引擎是否可用
     */
    fun isEnginesAvailable(): Boolean {
        synchronized(engineLock) {
            val available = isInitialized && !isDestroyed &&
                    ftEngine != null && frEngine != null && flEngine != null
            Log.d(
                TAG,
                "检查引擎可用性: isInitialized=$isInitialized, isDestroyed=$isDestroyed, available=$available"
            )
            return available
        }
    }

    /**
     * 获取当前引用计数
     */
    fun getReferenceCount(): Int {
        synchronized(engineLock) {
            return referenceCount
        }
    }

    /**
     * 重置引擎状态（用于引擎恢复）
     */
    fun resetEngineState() {
        synchronized(engineLock) {
            Log.i(TAG, "重置引擎状态")
            isDestroyed = false
            referenceCount = minReferenceCount
        }
    }

    /**
     * 重新初始化引擎（用于引擎被销毁后的恢复）
     */
    private fun reinitializeEngines(context: Context, maxDetectNum: Int): Boolean {
        synchronized(engineLock) {
            if (!isDestroyed) {
                Log.d(TAG, "引擎未销毁，无需重新初始化")
                return true
            }

            try {
                Log.i(TAG, "=== 开始重新初始化人脸识别引擎 ===")

                // 重置状态
                isDestroyed = false
                isInitialized = false
                referenceCount = 0
                minReferenceCount = 1

                // 清理可能存在的引擎实例
                cleanupEngines()

                // 重新初始化引擎
                val success = initEngines(context, maxDetectNum)
                if (success) {
                    Log.i(TAG, "=== 人脸识别引擎重新初始化成功 ===")
                } else {
                    Log.e(TAG, "=== 人脸识别引擎重新初始化失败 ===")
                }

                return success

            } catch (e: Exception) {
                Log.e(TAG, "重新初始化引擎时发生异常", e)
                return false
            }
        }
    }
} 